﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using BPM.Entity;
using BPM.ViewModel;
using System.Linq.Expressions;
using System.Reflection;
using BPM.Web;
using System.Web.Script.Serialization;
using BPM.Common;
using System.IO;
using System.Web;
using hxy.CopyRight;

namespace BPM
{
	public class BaseController : Controller
	{
		protected virtual Role[] GetCheckRoles()
		{
			return new Role[0];
		}

		protected virtual bool CheckRoles(User curUser, Role[] roles)
		{
			//如果有任意一个角色，则算成功
			return roles.Any(r => curUser.HasRole(r));
		}

		protected override void OnAuthorization(AuthorizationContext filterContext)
		{
			var roles = GetCheckRoles();
			if (roles.Length > 0)
			{
				var curUser = this.CurrentUser;
				if (curUser == null)
				{
					filterContext.Result = RedirectToAction(ad => ad.Logon.Logon);
				}
				else if (!curUser.IsValid)
				{
					filterContext.Result = RedirectToAction(ad => ad.Logon.WaitVerification);
				}
				else
				{
					if (!CheckRoles(curUser, roles))
					{
						filterContext.Result = RedirectToAction(ad => ad.Logon.Logon);
					}
				}
			}

			base.OnAuthorization(filterContext);
		}

		protected override void OnActionExecuting(ActionExecutingContext filterContext)
		{
			//如果产品没有注册，不能使用。
			DateTime time = default(DateTime);
			if (!ProductRegister.HasRegistered(out time) ||
				time < DateTime.Now
				)
			{
				filterContext.Result = RedirectToAction(ad => ad.Error.NotAuthoticated);
			}

			base.OnActionExecuting(filterContext);
		}

		/// <summary>Z
		/// 标记virtual后，可以使用Mock
		/// </summary>
		public User CurrentUser
		{
			get
			{
				return DPHost.Context.GetCurrentUser(this.HttpContext);
			}
			set
			{
				DPHost.Context.SetCurrentUser(this.HttpContext, value);
			}
		}

		/// <summary>
		/// <![CDATA[
		/// how to use:
		/// return View(() => AD.InternalDefaultView.Default);
		/// ]]>
		/// </summary>
		/// <param name="action"></param>
		/// <returns></returns>
		public ViewResult View(Expression<Func<AD, string>> action)
		{
			var pair = AD.Read(action);
			return View(pair.Action);
		}

		/// <summary>
		/// <![CDATA[
		/// how to use:
		/// return RedirectToAction(() => AD.InternalDefaultView.Default);
		/// ]]>
		/// </summary>
		/// <param name="action"></param>
		/// <returns></returns>
		public RedirectToRouteResult RedirectToAction(Expression<Func<AD, string>> action)
		{
			var pair = AD.Read(action);

			return RedirectToAction(pair.Action, pair.Controller);
		}

		protected static string JsonString(object obj)
		{
			var serializer = new JavaScriptSerializer();
			string json = serializer.Serialize(obj);
			return json;
		}

		protected static int ParseInt(string value, int defaultValue = 0)
		{
			int i;
			if (int.TryParse(value, out i)) return i;
			return defaultValue;
		}

		protected static int ParsePositiveInt(string value, int defaultValue = 0)
		{
			int i;
			if (int.TryParse(value, out i) && i > 0) return i;
			return defaultValue;
		}

		public Result SaveImage(HttpPostedFileBase file, string relative)
		{
			var enabledExt = new string[] { ".jpg", ".png", ".gif" };
			var ext = Path.GetExtension(file.FileName).ToLower();
			if (!enabledExt.Contains(ext)) return "只能上传图片。";

			return SaveFile(file, relative);
		}

		public Result SaveFile(HttpPostedFileBase file, string relative)
		{
			try
			{
				string filePath = CalculateFileName(file.FileName, relative);

				//save file
				file.SaveAs(filePath);

				//return the filename saved in the disk
				return new Result(true, Path.GetFileName(filePath));
			}
			catch
			{
				return "上传文件失败。";
			}
		}

		public string CalculateFileName(string file, string relativeDirectoryPath)
		{
			//Ensure this directory existing.
			string userDirectory = Server.MapPath(relativeDirectoryPath);
			if (Directory.Exists(userDirectory) == false)
			{
				Directory.CreateDirectory(userDirectory);
			}

			//combine to a physical path.
			string fileName = userDirectory + Path.GetFileName(file);

			//if this file has existed, save it as its name of current time.
			if (System.IO.File.Exists(fileName))
			{
				fileName = userDirectory + DateTime.Now.Ticks + Path.GetExtension(file);
			}
			return fileName;
		}
	}
}